/**
 * Created by kennylee on 25/7/2017.
 */
// Uses Node, AMD or browser globals to create a module.
(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory(require('jquery'));
    } else {
        // Browser globals (root is window)
        root.carousel = factory(root.jQuery);
    }
}(this, function ($) {
    "use strict";

    function getPhotoProperty($firstItem, count, idx) {
        if (count !== 5 || idx > 4 || idx < 0) {
            alert('unsupported yet!');
            return;
        }
        var o, _left = 0, _top = 0, _width = 0, _height = 0, _zIndex = 1;

        function _mark() {
            return {
                'left': _left,
                'top': _top,
                'width': _width,
                'height': _height,
                'zIndex': _zIndex
            };
        }

        switch (idx) {
            case 0: {
                _left = $firstItem.offset().left;
                _top = $firstItem.offset().top;
                _width = $firstItem.width();
                _height = $firstItem.height();
                _zIndex = 10;
                o = _mark();
                break;
            }
            case 1: {
                _left = $firstItem.offset().left + $firstItem.width() * 0.4 + 30;
                _top = $firstItem.offset().top - 50;
                _width = $firstItem.width() * 0.6;
                _height = $firstItem.height() * 0.6;
                _zIndex = 9;
                o = _mark();
                break;
            }
            case 2: {
                _left = $firstItem.offset().left + $firstItem.width() * 0.4 - 30;
                _top = $firstItem.offset().top - 80;
                _width = $firstItem.width() * 0.6;
                _height = $firstItem.height() * 0.6;
                _zIndex = 8;
                o = _mark();
                break;
            }
            case 3: {
                _left = $firstItem.offset().left + $firstItem.width() * 0.5 - 120;
                _top = $firstItem.offset().top - 70;
                _width = $firstItem.width() * 0.5;
                _height = $firstItem.height() * 0.5;
                _zIndex = 7;
                o = _mark();
                break;
            }
            case 4: {
                _left = $firstItem.offset().left + $firstItem.width() * 0.6 - 190;
                _top = $firstItem.offset().top - 50;
                _width = $firstItem.width() * 0.4;
                _height = $firstItem.height() * 0.4;
                _zIndex = 6;
                o = _mark();
                break;
            }
            default: {
                break;
            }
        }
        return o;
    }

    function Carousel(options) {
        this._coords = [];
        this.maxIndex = this.getItems().size() - 1;
        this.options = $.extend({}, this.constructor.defaults);
        this.option(options);
        this.switchIntervalId = 0;

        this.init();
    }

    Carousel.defaults = {
        number: 'carousel-number',
        activeClass: 'active',
        delay: 600,
        autoSwitch: true,
        switchDelay: 5000
    };

    Carousel.prototype.option = function (options) {
        $.extend(this.options, options);
    };

    Carousel.prototype.getItems = function () {
        return $('.carousel .item');
    };

    Carousel.prototype._initPhotoCoordsProperties = function () {
        var $items = this.getItems();
        var _self = this;
        $items.each(function (idx) {
            var o = getPhotoProperty($items.first(), 5, idx);
            if (!$.isEmptyObject(o)) {
                _self._coords[_self._coords.length] = o;
            }
        });
    };

    Carousel.prototype.tranItem = function ($item, coordIdx) {
        var c = this._coords[coordIdx];
        if (c) {
            $item.css(c).data(this.options.number, coordIdx)
                .removeClass(this.options.activeClass)
                .find('img').css({
                'width': c['width'],
                'height': c['height']
            });
        }
        return $item;
    };

    Carousel.prototype._setupEvents = function () {
        var _self = this;
        var nextEvent = function (e) {
            var $items = _self.getItems();
            if (!$(this).hasClass(_self.options.activeClass) || e.target.tagName.toUpperCase() !== 'IMG') {
                e.stopPropagation();
                return;
            }
            _self._stopAutoSwitch();
            $items.each(function () {
                var $self = $(this);
                var current_num = $self.data(_self.options.number);
                current_num--;
                if (current_num < 0) {
                    current_num = 4;
                }
                _self.tranItem($self, current_num);
                if (current_num === 0) {
                    window.setTimeout(function () {
                        $self.addClass(_self.options.activeClass);
                        _self._setupAutoSwitch();
                    }, _self.options.delay);
                }
            });
        };
        this.getItems().on('click', nextEvent);
    };

    Carousel.prototype._setupAutoSwitch = function () {
        if (!this.options.autoSwitch) {
            return;
        }
        var _self = this;
        this.switchIntervalId = window.setTimeout(function () {
            var $target = _self.getItems().filter('.' + _self.options.activeClass).find('img');
            if ($target.length > 0) {
                $target.trigger('click');
            }
        }, this.options.switchDelay);
    };

    Carousel.prototype._stopAutoSwitch = function () {
        if (this.switchIntervalId) {
            window.clearTimeout(this.switchIntervalId);
        }
    };

    Carousel.prototype.init = function () {
        this._initPhotoCoordsProperties();
        var _self = this;
        _self.getItems().each(function (idx) {
            var $self = $(this);
            _self.tranItem($self, idx).addClass('tran');
            if (idx === 0) {
                $self.addClass(_self.options.activeClass);
            }
        });
        this._setupEvents();
        this._setupAutoSwitch();
    };

    $(function () {
        new Carousel();
    });
}));